/*
 * Copyright 2010 Kevin L'Huillier <klhuillier@gmail.com>
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package org.lhuillier.pwsafe.io.codec;


import java.util.List;
import org.lhuillier.pwsafe.io.RawDb;
import org.lhuillier.pwsafe.model.Database;
import org.lhuillier.pwsafe.model.RawField;
import org.lhuillier.pwsafe.model.Record;
import com.google.inject.Inject;


class RawDbEncoderImpl implements RawDbEncoder {
    private final BinConverter binConv;
    private final List<HeaderConverter> headerCodecs;
    private final List<FieldConverter> fieldCodecs;
    
    @Inject
    RawDbEncoderImpl(BinConverter binConv, List<HeaderConverter> headerCodecs,
            List<FieldConverter> fieldCodecs) {
        this.binConv = binConv;
        this.headerCodecs = headerCodecs;
        this.fieldCodecs = fieldCodecs;
    }
    
    @Override
    public RawDb dbToRaw(Database db) {
        RawDb result = new RawDb();
        doHeader(result, db);
        doRecords(result, db);
        return result;
    }

    void doHeader(RawDb raw, Database db) {
        raw.addHeader(new RawField((byte) 1, binConv.writeUuid(db.getUuid())));
        
        for (HeaderConverter codec : headerCodecs) {
            codec.toRaw(db, raw);
        }
        for (RawField field : db.getUnknownFields()) {
            raw.addHeader(field);
        }
    }

    void doRecords(RawDb raw, Database db) {
        for (Record record : db.getRecords()) {
            doRecord(raw, record);
        }
    }

    void doRecord(RawDb raw, Record record) {
        RawRecord result = new RawRecord();
        
        result.addField(new RawField((byte) 1, binConv.writeUuid(
                record.getUuid())));
        
        for (FieldConverter codec : fieldCodecs) {
            codec.toRaw(record, result);
        }
        for (RawField field : record.getUnknownFields()) {
            result.addField(field);
        }

        raw.addRecord(result);
    }

}
